package com.kotlinvben.controller

import com.kotlinvben.bean.PageData
import com.kotlinvben.bean.Result
import com.kotlinvben.entity.User
import com.kotlinvben.service.UserService
import com.kotlinvben.utils.SecurityUtils
import com.kotlinvben.vo.UserCreateVO
import com.kotlinvben.vo.UserUpdateVO
import com.kotlinvben.vo.UserVO
import com.kotlinvben.vo.UserEnabledVO
import org.springframework.data.domain.PageRequest
import org.springframework.web.bind.annotation.*
import jakarta.validation.Valid
import org.springframework.data.domain.Sort.Direction.ASC
import org.springframework.data.domain.Sort.by

@RestController
@RequestMapping("/system/user")
class UserController(
    private val userService: UserService
) {
    @PostMapping
    fun createUser(@Valid @RequestBody userCreateVO: UserCreateVO): Result<UserVO> {
        val username = SecurityUtils.getCurrentUsername()
        val user = User(
            username = userCreateVO.username,
            realName = userCreateVO.realName,
            password = userCreateVO.password,
            email = userCreateVO.email,
            gender = userCreateVO.gender,
            phone = userCreateVO.phone,
            address = userCreateVO.address,
            status = userCreateVO.status,
            department = userCreateVO.department,
            createBy = username,
            modifyBy = username
        )
        val createdUser = userService.createUser(user, userCreateVO.roleIds)
        return Result.success(
            UserVO(
                createdUser.id,
                createdUser.username,
                createdUser.realName,
                createdUser.email,
                createdUser.gender,
                createdUser.phone,
                createdUser.address,
                createdUser.status,
                createdUser.department,
                createdUser.remark,
                createdUser.createTime!!
            )
        )
    }

    @PutMapping("/{id}")
    fun updateUser(@PathVariable id: Long, @Valid @RequestBody updateVO: UserUpdateVO): Result<UserVO> {
        val updatedUser = userService.updateUser(id, updateVO)
        return Result.success(
            UserVO(
                updatedUser.id,
                updatedUser.username,
                updatedUser.realName,
                updatedUser.email,
                updatedUser.gender,
                updatedUser.phone,
                updatedUser.address,
                updatedUser.status,
                updatedUser.department,
                updatedUser.remark,
                updatedUser.createTime!!
            )
        )
    }

    @DeleteMapping("/{id}")
    fun deleteUser(@PathVariable id: Long): Result<Unit> {
        userService.deleteUser(id)
        return Result.success()
    }

    @PutMapping("/{id}/disable")
    fun updateUserDisable(
        @PathVariable id: Long,
        @RequestBody enabledVO: UserEnabledVO
    ): Result<Unit> {
        userService.updateUserStatus(id, enabledVO.status)
        return Result.success()
    }

    @GetMapping("/{id}")
    fun getUserById(@PathVariable id: Long): Result<UserVO> {
        return userService.getUserById(id)?.let {
            Result.success(
                UserVO(
                    id = it.id,
                    username = it.username,
                    realName = it.realName,
                    email = it.email,
                    gender = it.gender,
                    phone = it.phone,
                    address = it.address,
                    department = it.department,
                    status = it.status,
                    remarks = it.remark,
                    createTime = it.createTime!!
                )
            )
        } ?: Result.notFound()
    }

    @GetMapping("/list")
    fun getUsers(
        @RequestParam(defaultValue = "0") page: Int,
        @RequestParam(defaultValue = "10") size: Int,
        @RequestParam(required = false) name: String?,
        @RequestParam(required = false) email: String?,
        @RequestParam(required = false) phone: String?,
        @RequestParam(required = false) status: Int?,
    ): Result<PageData<UserVO>> {
        val pageable = PageRequest.of(if (page > 0) page - 1 else page, size, by(ASC, "id"))
        val users = userService.getUsers(pageable, name, email, phone, status)
        val voList = users.content.map { user ->
            UserVO(
                id = user.id,
                username = user.username,
                realName = user.realName,
                email = user.email,
                gender = user.gender,
                phone = user.phone,
                address = user.address,
                department = user.department,
                status = user.status,
                remarks = user.remark,
                createTime = user.createTime!!,
                roles = user.roles.map { role -> role.name }.toMutableList(),
                roleIds = user.roles.map { it.id!! }
            )
        }
        return Result.success(
            PageData.of(
                items = voList,
                total = users.totalElements,
                page = page,
                size = size
            )
        )
    }
} 